<?php

/**
 * Created by PhpStorm.
 * User: shengjun
 * Date: 2018/6/19
 * Time: 16:57
 */

namespace api\components\utils;

use common\components\Curl;
use Yii;

//define('X_PI',3.14159265358979324*3000.0/180.0);

class GeoTransUtil
{

    const TRANSFORM_WGS84_TO_CD = '/coordinate/transformWGS84';
    const TRANSFORM_CD_TO_WGS84 = '/coordinate/transformCD';

    private static $x_pi = 3.14159265358979324 * 3000.0 / 180.0;
    private static $pi = 3.14159265358979324;
    private static $a = 6378245.0;
    private static $ee = 0.00669342162296594323;

//火星坐标(GCJ02坐标，高德，谷歌，腾讯坐标)到百度坐标BD-09
    public static function gcjTObd($from)
    {
        $to = new Coordinate();
        $x = $from->y;
        $y = $from->x;
        $z = sqrt($x * $x + $y * $y) + 0.00002 * sin($y * self::$x_pi);
        $theta = atan2($y, $x) + 0.000003 * cos($x * self::$x_pi);
        $to->y = $z * cos($theta) + 0.0065;
        $to->x = $z * sin($theta) + 0.006;

        return ($to);
    }

    //百度坐标BD-09到火星坐标GCJ02(高德，谷歌，腾讯坐标)
    public static function bdTOgcj($from)
    {
        $to = new Coordinate();
        $x = $from->y - 0.0065;
        $y = $from->x - 0.006;
        $z = sqrt($x * $x + $y * $y) - 0.00002 * sin($y * self::$x_pi);
        $theta = atan2($y, $x) - 0.000003 * cos($x * self::$x_pi);
        $to->y = $z * cos($theta);
        $to->x = $z * sin($theta);
        return ($to);
    }

    // WGS-84(GPS坐标，谷歌地球坐标) 到 GCJ-02(火星坐标) 的转换
    public static function wgsTOgcj($from)
    {
        //double wgLat, double wgLon, out double mgLat, out double mgLon
        $wgLat = $from->x;
        $wgLon = $from->y;
        if (self::outOfChina($wgLat, $wgLon)) {
            return (new Coordinate($wgLat, $wgLon));
        }

        $dLat = GeoTransUtil::transformLat($wgLon - 105.0, $wgLat - 35.0);
        $dLon = GeoTransUtil::transformLon($wgLon - 105.0, $wgLat - 35.0);
        $radLat = $wgLat / 180.0 * self::$pi;
        $magic = sin($radLat);
        $magic = 1 - self::$ee * $magic * $magic;
        $sqrtMagic = sqrt($magic);
        $dLat = ($dLat * 180.0) / ((self::$a * (1 - self::$ee)) / ($magic * $sqrtMagic) * self::$pi);
        $dLon = ($dLon * 180.0) / (self::$a / $sqrtMagic * cos($radLat) * self::$pi);

        $mgLat = $wgLat + $dLat;
        $mgLon = $wgLon + $dLon;

        return (new Coordinate($mgLat, $mgLon));
    }

    // GCJ-02 到 WGS-84 的转换
    public static function gcjTOwgs($from)
    {
        $to = self::wgsTOgcj($from);
        $lat = $from->x;
        $lon = $from->y;
        $g_lat = $to->x;
        $g_lon = $to->y;
        $d_lat = $g_lat - $lat;
        $d_lon = $g_lon - $lon;

        return new Coordinate($lat - $d_lat, $lon - $d_lon);
    }

    //把地球经纬度转换为lat和lng
    public static function earthCoordinate($t1, $t2)
    {
        $tt1 = $t1->x + $t1->y / 60.0 + $t1->z / 3600.0;
        $tt2 = $t2->x + $t2->y / 60.0 + $t2->z / 3600.0;

        return (new Coordinate($tt1, $tt2));
    }

    private static function outOfChina($lat, $lon)
    {
        if ($lon < 72.004 || $lon > 137.8347)
            return true;
        if ($lat < 0.8293 || $lat > 55.8271)
            return true;

        return false;
    }

    private static function transformLat($x, $y)
    {
        $ret = -100.0 + 2.0 * $x + 3.0 * $y + 0.2 * $y * $y + 0.1 * $x * $y + 0.2 * sqrt(abs($x));
        $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
        $ret += (20.0 * sin($y * self::$pi) + 40.0 * sin($y / 3.0 * self::$pi)) * 2.0 / 3.0;
        $ret += (160.0 * sin($y / 12.0 * self::$pi) + 320 * sin($y * self::$pi / 30.0)) * 2.0 / 3.0;
        return $ret;
    }

    private static function transformLon($x, $y)
    {
        $ret = 300.0 + $x + 2.0 * $y + 0.1 * $x * $x + 0.1 * $x * $y + 0.1 * sqrt(abs($x));
        $ret += (20.0 * sin(6.0 * $x * self::$pi) + 20.0 * sin(2.0 * $x * self::$pi)) * 2.0 / 3.0;
        $ret += (20.0 * sin($x * self::$pi) + 40.0 * sin($x / 3.0 * self::$pi)) * 2.0 / 3.0;
        $ret += (150.0 * sin($x / 12.0 * self::$pi) + 300.0 * sin($x / 30.0 * self::$pi)) * 2.0 / 3.0;
        return $ret;
    }

    // WGS-84(GPS坐标，谷歌地球坐标) 到 城地 的转换(批量）
    public static function batchWgsTOcd($coordinates)
    {
        $curl = new Curl();
        $url = \Yii::$app->params['transformServerRoot']['base_url']. \Yii::$app->params['transformServerRoot']['root']. self::TRANSFORM_WGS84_TO_CD;
        if (!empty($coordinates) && !is_array($coordinates)) {
            $coordinates[] = $coordinates;
        }
        $result = $curl->setHeader('Content-Type', 'application/json')->setRawPostData(json_encode($coordinates))->post($url, false);
        return $result;
    }

     // WGS-84(GPS坐标，谷歌地球坐标) 到 城地 的转换
    public static function wgsTOcd($from)
    {
        $curl = new Curl();
        $url = \Yii::$app->params['transformServerRoot']['base_url']. self::TRANSFORM_WGS84_TO_CD;
        if (!empty($from)) {
            $coordinates[] = [$from->y, $from->x];
        }
        $result = $curl->setHeader('Content-Type', 'application/json')->setRawPostData(json_encode($coordinates))->post($url, false);
        if (!empty($result) && !$result->hasErrors() && !empty($result->getData())) {
            $current = current($result->getData());
            return new Coordinate($current[1], $current[0]);
        }
        return [];
    }

    //城地 到 WGS-84
    public static function cd2wgs($from)
    {
        $curl = new Curl();
        $url = \Yii::$app->params['transformServerRoot']['base_url']. self::TRANSFORM_CD_TO_WGS84;
        if (!empty($from)) {
            $coordinates[] = [$from->y, $from->x];
        }
        $result = $curl->setHeader('Content-Type', 'application/json')->setRawPostData(json_encode($coordinates))->post($url, false);
        if (!empty($result) && !$result->hasErrors() && !empty($result->getData())) {
            $current = current($result->getData());
            return new Coordinate($current[1], $current[0]);
        }
        return [];
    }

    //地址反查经纬度
    public static function getCoodFromAddress($address)
    {
        $final = [];
        $curl = new Curl();
        $url = isset(Yii::$app->params['geo_service']['citygis_url']) ? Yii::$app->params['geo_service']['citygis_url'] : 'http://172.36.19.86:8899/meta/address_translate';
        $params = [
            'address' => $address
        ];
        $result = $curl->setGetParams($params)->get($url, false);
        if (!empty($result) && !$result->hasErrors()) {
            $response = $result->getData();
            if (isset($response['jiedao']) && isset($response['qu'])) {
                $final['grid_code'] = isset($response['ext']['grid_id']) ? $response['ext']['grid_id'] :  '';
                $final['grid_id'] = isset($response['ext']['grid_id']) ? $response['ext']['grid_id'] :  '';
                $final['street_code'] = isset($response['ext']['street_id']) ? intval($response['ext']['street_id']) : 0;
                $final['district_code'] = isset($response['ext']['district_id']) ? intval($response['ext']['district_id']) : 0;
                $final['community_name'] = isset($response['ext']['juweihui_name']) ? $response['ext']['juweihui_name'] : '';
                $final['community_id'] = isset($response['ext']['juweihui_id']) ? $response['ext']['juweihui_id'] : '';
            }
        }
        return $final;
    }

   //城地详情接口
    public static function getGeoInfo($signX, $signY)
    {
        $return = [];
        $curl = new Curl();
        $url = isset(Yii::$app->params['geo_service']['base_url']) ? Yii::$app->params['geo_service']['base_url'] : 'http://10.81.71.51/gservice/layerCountByCondition';
        $areaID = isset(Yii::$app->params['geo_service']['area_id']) ? Yii::$app->params['geo_service']['area_id'] : 'city';
        $where = isset(Yii::$app->params['geo_service']['where']) ? Yii::$app->params['geo_service']['where'] : '1=1';
        $text = isset(Yii::$app->params['geo_service']['text']) ? Yii::$app->params['geo_service']['text'] : '';
        $distance = isset(Yii::$app->params['geo_service']['distance']) ? Yii::$app->params['geo_service']['distance'] : '';
        $token = isset(Yii::$app->params['geo_service']['token']) ? Yii::$app->params['geo_service']['token'] : 'TVRJek5EVTJRRUJBTWpBd01BPT1ZV1J0YVc1QVFFQmphWFI1WjJseg==';
        $params = [
            'areaID' => $areaID,
            'where' => $where,
            'text' => $text,
            'distance' => $distance,
            'token' => $token,
            'point.x' => $signX,
            'point.y' => $signY,
        ];
        $result = $curl->setGetParams($params)->get($url, false);
        if (!empty($result) && !$result->hasErrors()) {
            $response = $result->getData();
            if (isset($response['status']) && $response['status'] == 1) {
                $return['grid_code'] = $return['grid_name'] = $response['data']['网格编码'];
                $return['street_code'] = $response['data']['街道代码'];
                $return['street_name'] = $response['data']['所属街道'];
                $return['district_code'] = $response['data']['区代码'];
                $return['district_name'] = $response['data']['所属区县'];
                $return['district_code'] = $response['data']['区代码'];
                $return['community_name'] = $response['data']['居委会名称'] ?? '';
                $return['community_id'] = $response['data']['居委会代码'] ?? '';
            }
        }
        return $return;
    }
}
